import { DownOutlined, HomeOutlined, PlusOutlined } from '@ant-design/icons';
import { Alert, Breadcrumb, Button, Empty, Tree } from 'antd';
import { history, useModel } from 'umi';
import { arrayMoveImmutable, isEqual, last } from '@szzj/utils';
import { findChildrenKeyListByParentId } from './utils';
import EditDrawer from './components/EditDrawer';
import MetaInfo from './components/MetaInfo';
import Container from './hooks';
import styles from './index.less';
import type { IEnums } from '@/types/global';
import type { JumpWayEnum, MenuTypeEnum } from '@/types/systemManagement/menu';
import { filterBtn } from '@/pages/systemManagement/menu/utils';
import { PageContainer } from '@ant-design/pro-components';

function Index() {
  const {
    editDrawerOpen,
    setEditDrawerOpen,
    setEditingId,
    postMenuFindWholeTreeRequest,
    postMenuSortRequest,
  } = Container.useContainer();
  const { hasPermisson } = useModel('useUser', (model) => {
    return {
      hasPermisson: model.getRole,
    };
  });
  return (
    <PageContainer
      header={{
        title: false,
      }}
    >
      <div className={styles.content}>
        <Alert
          showIcon
          style={{ marginBottom: 16 }}
          message={<div>拖动菜单可以进行排序（不支持跨级排序或跨目录排序）</div>}
        />
        <div style={{ textAlign: 'right' }}>
          <Button
            type="primary"
            icon={<PlusOutlined />}
            // disabled={!hasPermisson('MENU_CREATE_CATALOG') && !hasPermisson('MENU_CREATE_MENU')}
            onClick={() => {
              setEditDrawerOpen(true);
            }}
            style={{ marginBottom: 8 }}
          >
            新增
          </Button>
        </div>
        {!!postMenuFindWholeTreeRequest?.data?.length ? (
          <Tree
            treeData={filterBtn(postMenuFindWholeTreeRequest.data)}
            blockNode
            draggable={{ icon: false }}
            allowDrop={({ dropNode, dropPosition, dragNode }) => {
              /**
               * 两个逻辑：
               * 1. 保证拖拽的节点和目标节点同级，且不能移动到同级节点内部（即dropPosition不能为0）
               * 2. 如果不同级，则必须只能拖动到父节点内部（不处理这个逻辑会出现子节点拖不到首位的情况）
               */
              return (
                (dropPosition !== 0 && dragNode?.parentId === dropNode?.parentId) ||
                (dragNode?.parentId === dropNode?.id && dropPosition === 0)
              );
            }}
            onDrop={(info) => {
              const dropPos = parseInt(last(info.node.pos.split('-')), 10);
              const dragPos = parseInt(last(info.dragNode.pos.split('-')), 10);
              /**
               * onDrop里面的info.dropPosition需要额外计算，计算结果和上面allowDrop的dropPosition一致
               * 在元素之上为-1，在元素之下的为1，拖动到元素内部为0
               */
              const dropPosition = info.dropPosition - dropPos;
              /** 最终位置根据从上到下或从下到上略有不同，从上到下需要额外-1 */
              const finalPos =
                dragPos < dropPos ? dropPos + dropPosition - 1 : dropPos + dropPosition;
              const currentTreeKeyList = findChildrenKeyListByParentId(
                postMenuFindWholeTreeRequest.data,
                info.dragNode?.parentId,
              );
              if (currentTreeKeyList) {
                const newTreeKeyList = arrayMoveImmutable(currentTreeKeyList, dragPos, finalPos);
                /** 只有当拖动后位置发生改变时才发起排序请求 */
                if (!isEqual(currentTreeKeyList, newTreeKeyList)) {
                  postMenuSortRequest.runAsync({ ids: newTreeKeyList }).then(() => {
                    postMenuFindWholeTreeRequest.refresh();
                  });
                }
              }
            }}
            selectable={false}
            switcherIcon={<DownOutlined style={{ marginTop: 15 }} />}
            titleRender={(node) => (
              <MetaInfo
                treeNodeId={node?.id}
                title={node?.name}
                content={node?.path}
                jumpWay={node?.isFrame}
                menuType={node?.menuType}
              />
            )}
          />
        ) : (
          <Empty image={Empty.PRESENTED_IMAGE_SIMPLE} />
        )}
        <EditDrawer
          open={editDrawerOpen}
          onClose={() => {
            setEditingId(undefined);
            setEditDrawerOpen(false);
          }}
        />
      </div>
    </PageContainer>
  );
}

export default () => {
  return (
    <Container.Provider>
      <Index />
    </Container.Provider>
  );
};
